#ifndef NGRAMAS_H_
#define NGRAMAS_H_

#include "cargadorDeArchivos.h"
#include <iostream>
#include <string>
#include <sstream>
#include <list>
#include <map>
#include <fstream>
#include <vector>
#include <set>
using namespace std;


struct sFreqArchivo{
	int indice;
	int frequencia;
	ofstream* archivo;
	ofstream* archivoDeApariciones;
};














struct palabraYProbabilidad{
	string palabra;
	float probabilidad;
};

struct palabrasDeTrigrama{
	/*
	string segundaPalabra;
	string terceraPalabra;
	*/
	int segundaPalabra;
	int terceraPalabra;

};

struct comparadorDeTrigramas{
	bool operator()(const palabrasDeTrigrama trigrama1, const palabrasDeTrigrama trigrama2) const{

		if (trigrama1.segundaPalabra != trigrama2.segundaPalabra){
			return (trigrama1.segundaPalabra < trigrama2.segundaPalabra);
		}
		else{
			return (trigrama1.terceraPalabra < trigrama2.terceraPalabra);
		}
	}
};





typedef struct _datosDeUnaPAlabraDelDiccionario{
	int indice;
	int frequencia;
	set<int>* apariciones;
	//map<palabrasDeTrigrama,int,comparadorDeTrigramas>* segundaYTerceraPalabra;
	map<palabrasDeTrigrama,int,comparadorDeTrigramas> segundaYTerceraPalabra;
} datosDeUnaPAlabraDelDiccionario;















//Se agrega con el formato: indice palabra2 - indice palabra3
void agregarTrigrama(string palabra1, string palabra2, string palabra3);

//Si no esta, la agrega con frecuencia 0 y archivo = nullptr
void agregarPalabraAlDiccionario(string palabra);

/*Si no esta, la agrega con frecuencia 0 y archivo = nullptr
  Ademas le suma 1 a la frecuencia
*/
void agregarPalabraSueltaAlDiccionario(string palabra);

void agregarTrigramas(vector<string> &palabras);

/*Se guarda con el formato: indice - palabra - frecuencia - direccion
  La direccion creo que no va a ser necesario guardarla
*/
void guardarDiccionario();

void guardarTrigramasAparicionesYVaciarDatos();




void cerrarArchivos();


void ordenarYReducirArchivoDeTrigramas(string palabraInicial);

//El formato final es: indice palabra2 - indice palabra3 - frecuencia
void guardarArchivoDeTrigramasReducido(map<palabrasDeTrigrama,int,comparadorDeTrigramas>* mapaDeTrigramas, string palabraInicial);


//-------------------------------------------------------------------------

size_t encontrarHueco(vector<string>* palabras, diccionario_t* dic, diccionarioPorIndice_t* dicPorIndice, mapaDeTrigramas_t* trigramas);

void obtenerCandidatas(string palabra1, string palabra2,
		diccionario_t* dic, diccionarioPorIndice_t* dicPorIndice,
		mapaDeTrigramas_t* trigramas,
		vector<palabraYProbabilidad>* vec);

#endif
